package com.fingard.dsp.bank.directbank.citic43;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.sql.Connection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @author Parker on 2019-10-08.
 * @version 1.0
 */
public class CITIC43SinglePay extends CITIC43Base implements ISinglePay {
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        //齐鲁社保一代支付
        return d_one_1908_SglPay(p_req1908);
    }

    public RetAtsSingle d_one_1908_SglPay(ReqSingle p_req1908) throws Exception {
        //返回ATS的对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        Connection conn = FGBiz.getLocalDbConn();
        CITIC43Header header = new CITIC43Header();
        header.head = "012509801 012590090000200012590090000200JNWL    yc0012         ";
        header.serviceId = "8000";
        header.transSeq = Format.DateTime14Format.format(new Date())+StringHelper.padLeft("1",6,'0');
        //记录ats支付流水号对应的消息流水号，供查询状态接口使用
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1908.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1908.singleDetail.askNumber, header.transSeq,""});

        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        try {
            StringBuilder sbContent = new StringBuilder();
            writeCommonHeader(header, sbContent);
            sbContent.append(Format.Date8Format.format(Format.Date10Format.parse(p_req1908.singleDetail.payDate))).append(fieldUnionChar);
            sbContent.append(p_req1908.singleDetail.payAmount).append(fieldUnionChar);//支付金额
            sbContent.append("0").append(fieldUnionChar);//交易类型 借贷 0：一借一贷
            //1 实体账户到过渡账户  0 过渡账户到实体账户 -1无配置数据
            String payActType = getBankConfig().getMapAdvanceValue("ActInfo","key","actType",p_req1908.singleDetail.payAct);
            String recActType = getBankConfig().getMapAdvanceValue("ActInfo","key","actType",p_req1908.singleDetail.recAct);
            if("1".equals(payActType)&&"0".equals(recActType)){
                sbContent.append("1").append(fieldUnionChar);//记账方式 1：人工汇总（表示从付款帐户到过渡帐户）
                sbContent.append(p_req1908.singleDetail.payAct).append(fieldUnionChar);//付款人账号/主账号信息
                sbContent.append(p_req1908.singleDetail.payName).append(fieldUnionChar);//付款人户名
                sbContent.append(p_req1908.singleDetail.recAct).append(fieldUnionChar);//过渡账号
                sbContent.append(p_req1908.singleDetail.recName).append(fieldUnionChar);//过渡账号户名
                sbContent.append(p_req1908.singleDetail.recAct).append(fieldUnionChar);//收款人账号
                sbContent.append(p_req1908.singleDetail.recName).append(fieldUnionChar);//收款人账号名称
            }else if("0".equals(payActType)&&"1".equals(recActType)){
                sbContent.append("2").append(fieldUnionChar);//记账方式 2：机器汇总（表示从过渡帐户到收款帐户）
                sbContent.append(p_req1908.singleDetail.payAct).append(fieldUnionChar);//付款人账号/主账号信息
                sbContent.append(p_req1908.singleDetail.payName).append(fieldUnionChar);//付款人户名
                sbContent.append(p_req1908.singleDetail.payAct).append(fieldUnionChar);//过渡账号
                sbContent.append(p_req1908.singleDetail.payName).append(fieldUnionChar);//过渡账号户名
                sbContent.append(p_req1908.singleDetail.recAct).append(fieldUnionChar);//收款人账号
                sbContent.append(p_req1908.singleDetail.recName).append(fieldUnionChar);//收款人账号
            }else{
                WriteBankLogLn("账户类型未配置....");
            }
            sbContent.append("shebao").append(fieldUnionChar);//摘要信息，必填。用于区分不同业务。具体内容根据业务由银行端提供
            sbContent.append("1".equals(p_req1908.singleDetail.isPrivate)? "S":"G").append(fieldUnionChar);//付款账户公私标志 S：个人账户；G：对公账户。
            sbContent.append("N").append(fieldUnionChar);//部分退款标志 N：该笔交易为正常转账交易；Y：该笔交易为某笔交易的退款交易
            sbContent.append("").append(fieldUnionChar);//原交易流水号 部分退款标志为Y时生效，不能为空；部分退款标志为N时生效，可为空
            sbContent.append("").append(fieldUnionChar);//8字节，付款账户公私标志为G时，可为空
            sbContent.append("");//4字节，付款账户公私标志为G时，可为空
            String contentLength = String.format("%08d", sbContent.toString().getBytes("UTF-8").length);
            sbContent.insert(0,contentLength);
            String[] retStrArr = sendToBank(sbContent.toString());
            if (retStrArr[0].length() == 0) {
                retDetail.respCode = "0";
                retDetail.respInfo = "";
                retDetail.payInfoCode = retStrArr[1].split("\\"+fieldUnionChar)[3];
                retDetail.transState = retStrArr[1].split("\\"+fieldUnionChar)[3];
                retDetail.transAmt = p_req1908.singleDetail.payAmount;
                retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                retAts.writeRetDetail(retDetail);
            } else if (retStrArr[0].equals(ConnState.FAIL)) {
                retDetail.respCode = "0";
                retDetail.respInfo = retStrArr[1];
                retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                retDetail.transState = PaymentState.FAIL_Payment;
                retDetail.payInfoCode = retStrArr[0];
                WriteBankLogLn(retStrArr[1]);
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = retStrArr[1];
                retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                WriteBankLogLn(retStrArr[1]);
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
            WriteBankLogLn(e.getMessage());
        } finally {
            if(conn != null){
                conn.close();
            }
        }
        return retAts;
    }

    public RetAtsSingle d_twoGen_1908_SglPay(ReqSingle p_req1908) throws Exception {
        //返回ATS的对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        Connection conn = FGBiz.getLocalDbConn();
        CITIC43Header header = new CITIC43Header();
        header.head = "012509801 012590090000200012590090000200JNWL    yc0012         ";
        header.serviceId = "8000";
        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        try {
            StringBuilder sbMsg = new StringBuilder();
            writeCommonHeader(header, sbMsg);
            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
            xmlWriter.writeStartElement("ROOT");
            xmlWriter.writeElementString("requestId", p_req1908.reqHeader.transSeqID);
            xmlWriter.writeElementString("transtyp", "request");
            xmlWriter.writeElementString("transcode", "yc0016");
            xmlWriter.writeElementString("transchl", "0002");//渠道码  社保
            xmlWriter.writeElementString("txdate", Format.Date8Format.format(Format.Date10Format.parse(p_req1908.singleDetail.payDate)));
            xmlWriter.writeElementString("txtime", p_req1908.singleDetail.payTime.replace(":", ""));
            xmlWriter.writeElementString("fkacctno", p_req1908.singleDetail.payAct);
            xmlWriter.writeElementString("fkacnotyp", p_req1908.singleDetail.payAct);//0：内部账户；1：客户账户 TODO
            xmlWriter.writeElementString("custnm", p_req1908.singleDetail.recName);
            xmlWriter.writeElementString("custacctnum", p_req1908.singleDetail.recAct);
            xmlWriter.writeElementString("custhhh", p_req1908.singleDetail.cnapsCode);
            xmlWriter.writeElementString("custhmc", p_req1908.singleDetail.recBankName);
            xmlWriter.writeElementString("amount", p_req1908.singleDetail.payAmount);
            xmlWriter.writeElementString("stdtranamt", p_req1908.singleDetail.payAmount);
            xmlWriter.writeElementString("remark1", p_req1908.singleDetail.askNumber);//对账码
            xmlWriter.writeEndElement();
            xmlWriter.writeEndDocument();
            sbMsg.append(xmlWriter.toXmlString());
            String[] retStrArr = sendToBank(sbMsg.toString());
            if (retStrArr[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(retStrArr[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    retDetail.respCode = "0";
                    retDetail.respInfo = "";
                    retDetail.payInfoCode = "Paying";
                    retDetail.transState = "Paying";
                    retDetail.transAmt = p_req1908.singleDetail.payAmount;
                    retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                    //记录ats支付流水号对应的银行指令流水号，供查询状态接口使用
                    String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                    JDBCHelper.update(conn, INSERTSEQ, new Object[]{uuid, p_req1908.reqHeader.bankCode, Format.Date8Format.format(new Date()), p_req1908.singleDetail.askNumber, tmpBkReader.getFirstText("/ebank/head/orderFlowNo")});
                } else {
                    retDetail.respCode = "-1";
                    retDetail.respInfo = tmpSbMsg.toString();
                }
            } else if (retStrArr[0].equals(ConnState.FAIL)) {
                retDetail.respCode = "0";
                retDetail.respInfo = retStrArr[1];
                retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                retDetail.transState = PaymentState.FAIL_Payment;
                retDetail.payInfoCode = retStrArr[0];
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = retStrArr[1];
                retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
        } finally {
            if(conn != null){
                conn.close();
            }
        }
        retAts.writeRetDetail(retDetail);
        return retAts;
    }

    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail retDetail = new RetAtsSglDetail();
        Connection conn = FGBiz.getLocalDbConn();
        try {
            CITIC43Header header = new CITIC43Header();
            header.head = "012509801 012590090000200012590090000200JNWL    yc0013         ";
            header.serviceId = "9000";
            StringBuilder sbContent = new StringBuilder();
            writeCommonHeader(header, sbContent);
            Map<String, Object> selMap = JDBCHelper.execQuerySingle(conn, SELECTSEQ, new Object[]{p_req1944.askNumber, p_req1944.reqHeader.bankCode});
            if (selMap.size() > 0) {
                sbContent.append(selMap.get("BANKREQSEQID").toString()).append(fieldUnionChar);
                sbContent.append("yc0012");
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = "交易流水号关联映射异常，请检查";
                WriteBankLogLn("交易流水号关联映射异常，请检查");
                retAts.writeRetDetail(retDetail);
                return retAts;
            }
            String contentLength = String.format("%08d", sbContent.toString().getBytes("UTF-8").length);
            sbContent.insert(0,contentLength);
            String[] retStrArr = sendToBank(sbContent.toString());
            if (retStrArr[0].length() == 0) {
                retDetail.respCode = "0";
                retDetail.respInfo = "";
                retDetail.transState = retStrArr[1].split(fieldUnionChar)[1] + "+" + retStrArr[1].split(fieldUnionChar)[2];
                retDetail.payInfoCode = retDetail.transState;
                retDetail.transAmt = p_req1944.payAmount;
                retDetail.reqSeqID = p_req1944.askNumber;
            } else {
                retDetail.respCode = "-1";
                retDetail.respInfo = retStrArr[1];
                WriteBankLogLn(retStrArr[1]);
            }
        } catch (Exception e) {
            retDetail.respCode = "-1";
            retDetail.respInfo = e.getMessage();
            WriteBankLogLn(e.getMessage());
            e.printStackTrace();
        } finally {
            conn.close();
        }
        retAts.writeRetDetail(retDetail);
        return retAts;
    }
    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
